#ifndef CONNECTER_H_
#define CONNECTER_H_

#include <string>
#include <vector>
#include <mutex>
#include <atomic>

class event_base;
class ConnectHandler;
namespace AMQP
{
    class TcpConnection;
    class TcpChannel;
}
class Provider;
class Deliver;

/**
 * @class Connecter
 * @brief 定义一个连接器类，用于建立和维护与消息队列服务器的连接
 */
class Connecter
{
public:
    /**
     * @brief 构造函数，初始化连接器对象
     * @param id 连接器的唯一标识符
     * @param amqp_address 消息队列服务器的地址
     */
    explicit Connecter(int id, const std::string &amqp_address);

    /**
     * @brief 析构函数，释放连接器对象
     */
    ~Connecter();

    /**
     * @brief 启动连接器，开始连接消息队列服务器
     */
    void start();

    /**
     * @brief 运行事件循环，处理各种事件
     */
    void run();

    /**
     * @brief 设置连接器，包括建立到消息队列服务器的连接等
     * @return 成功返回true，否则返回false
     */
    bool setup();

    /**
     * @brief 通知连接器有事件发生
     * @param fd 文件描述符
     * @param which 事件类型
     */
    void notify(int fd, short which);

    /**
     * @brief 重新连接消息队列服务器
     */
    void reconnect();

    /**
     * @brief 添加一个消息提供者
     * @param provider 消息提供者对象指针
     */
    void addProvider(Provider *provider);

    /**
     * @brief 添加一个消息投递者
     * @param deliver 消息投递者对象指针
     */
    void addDeliver(Deliver *deliver);

private:
    /**
     * @brief 建立到消息队列服务器的连接
     */
    void connect();

    /**
     * @brief 发送消息
     * @param deliver 消息投递者对象指针
     */
    void send(Deliver* deliver);

    /**
     * @brief 发送并接收消息
     * @param deliver 消息投递者对象指针
     */
    void sendAndReceive(Deliver* deliver);

private:
    /// 连接器的唯一标识符
    int id_;
    /// 消息队列服务器的地址
    std::string amqp_address_;
    /// 事件基础对象，用于处理事件
    event_base *base_;
    /// 通知发送文件描述符
    int notify_send_fd_;
    /// 任务互斥锁，用于线程安全
    std::mutex task_mutex_;

    /// 连接处理对象
    ConnectHandler *handler_;
    /// TCP连接对象
    AMQP::TcpConnection *connection_;
    /// TCP通道对象
    AMQP::TcpChannel *channel_;
    /// 消息提供者列表
    std::vector<Provider *> providers_;
    /// 重新连接间隔时间
    int reconnect_interval_;
    /// 消息投递者列表
    std::vector<Deliver *> delivers_;
    /// 消息序列号，原子操作确保线程安全
    std::atomic<int> seq_;
};

#endif // CONNECTER_H_